<template>
    <div>
        <h1>{{type}}</h1>

        <el-form ref="myform" :model="myform" label-width="180px" :rules="rules">
            <el-form-item label="头像">
                <div 
                    class="add_avatar_btn" 
                    @click="add_avatar_btn" 
                    :style="{'background-image': avatarServerFileName ? `url(http://www.zkt-it.com:5050/images/student_avatar/${avatarServerFileName})` : ''}"
                >
                    <span v-show="avatarServerFileName == ''">
                        +
                    </span>
                </div>

                <!-- 这里要放置一个隐藏（hidden）的文件选择框 -->
                <input type="file" hidden ref="file_kuang" @change="pick_picture_done($event)">
            </el-form-item>
            
            <!-- ********************** -->
            <!-- 表单项 -->
            <!-- ********************** -->
            <el-form-item label="学号" prop="sId">
                <el-input v-model="myform.sId"></el-input>
            </el-form-item>

            <!-- ********************** -->
            <!-- 表单项 -->
            <!-- ********************** -->
            <el-form-item label="姓名" prop="name">
                <el-input v-model="myform.name"></el-input>
            </el-form-item>

            <!-- ********************** -->
            <!-- 表单项 -->
            <!-- ********************** -->
            <el-form-item label="性别" prop="sex">
                <el-radio-group v-model="myform.sex">
                    <el-radio label="男"></el-radio>
                    <el-radio label="女"></el-radio>
                </el-radio-group>
            </el-form-item>

            <!-- ********************** -->
            <!-- 表单项 -->
            <!-- ********************** -->
            <el-form-item label="手机号码" prop="tel">
                <el-input v-model="myform.tel"></el-input>
            </el-form-item>

            <!-- ********************** -->
            <!-- 单选按钮 -->
            <!-- ********************** -->
            <el-form-item label="政治面貌" prop="politics_status">
                <el-radio-group v-model="myform.politics_status">
                    <el-radio label="党员"></el-radio>
                    <el-radio label="预备党员"></el-radio>
                    <el-radio label="共青团员"></el-radio>
                    <el-radio label="群众"></el-radio>
                </el-radio-group>
            </el-form-item>

            <!-- ********************** -->
            <!-- 日期选择框 -->
            <!-- ********************** -->
            <el-form-item label="生日" prop="birthDay">
                <LunarCalendar v-model="myform.birthDay"></LunarCalendar>
            </el-form-item>

            <!-- ********************** -->
            <!-- 级联选择器 -->
            <!-- ********************** -->
            <el-form-item label="学院专业和班级" prop="cmc">
                <el-cascader filterable clearable :options="cmcOptions" style="width:500px;" v-model="myform.cmc">
                </el-cascader>
            </el-form-item>

            <!-- ********************** -->
            <!-- 下拉菜单 -->
            <!-- ********************** -->
            <el-form-item label="入学年份" prop="enrollmentYear">
                <el-select v-model="myform.enrollmentYear" placeholder="请选择入学年份" :clearable="true">
                    <el-option label="2019" value="2019"></el-option>
                    <el-option label="2020" value="2020"></el-option>
                    <el-option label="2021" value="2021"></el-option>
                    <el-option label="2022" value="2022"></el-option>
                </el-select>
            </el-form-item>

            <!-- ********************** -->
            <!-- 下拉菜单 -->
            <!-- ********************** -->
            <el-form-item label="在读状态" prop="state">
                <el-select v-model="myform.state" placeholder="请选择在读状态" :clearable="true">
                    <el-option label="在读" :value="1" />
                    <el-option label="休学" :value="2" />
                    <el-option label="退学" :value="3" />
                </el-select>
            </el-form-item>

            <!-- ********************** -->
            <!-- 下拉菜单 -->
            <!-- ********************** -->
            <el-form-item label="民族" prop="nationality">
                <el-select v-model="myform.nationality" placeholder="请选择民族" :clearable="true" filterable>
                    <el-option v-for="(item, index) in allNationality" :key="index" :label="item" :value="item">
                    </el-option>
                </el-select>
            </el-form-item>

            <!-- 提交按钮 -->
            <el-form-item>
                <el-button type="primary" @click="addStudent()" v-if="type=='增加学生'">
                    确定增加学生
                </el-button>
                
                <el-button type="primary" @click="modifyStudent()" v-if="type=='修改学生'">
                    确定修改学生
                </el-button>
            </el-form-item>
        </el-form>

        <!-- 弹出层 -->
        <el-dialog :visible="showCutDialog" @close="showCutDialog=false">
            <div slot="title">
                剪裁头像
            </div>

            <!-- 内部组件 -->
            <CutImageDialogInn v-if="showCutDialog" ref="CutImageDialogInn" :picURL="picURL"/>

            <div slot="footer">
                <el-button type="success" @click="doCut">确定裁切</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import { fetchCMC, addStudent, modifyStudent, getOneStudentDedail, uploadAvatar, serverDoCut } from '@/api/student.js';
import LunarCalendar from '@/components/LunarCalendar.vue';
import CutImageDialogInn from  './CutImageDialogInn.vue';
export default {
    // 定义组件
    components: {
    CutImageDialogInn,
    LunarCalendar
},
    // 生命周期
    async created() {
        // 学号
        this.sid = this.$route.query.sid;
        // 设置页面的类型，这个页面是同时给增加、修改使用的
        this.type = this.$route.name;

        // 如果是增加学生
        if (this.type == '增加学生') {
            // 拉取CMC数据
            let cmcData = await fetchCMC();
            // 转换数据
            this.handleCmcToSelectTree(cmcData);
        } else {
            let res = await Promise.all([
                fetchCMC(),
                getOneStudentDedail(this.sid)
            ]);

            // 转换数据
            this.handleCmcToSelectTree(res[0]);
            // 回显数据
            this.showBackData(res[1]);
        }
    },
    data() {
        return {
            // 是否显示裁切框
            showCutDialog: false,
            // 上传之后的原始的文件名
            serverOfilename: '',
            // 头像的URL
            picURL: '',
            // 头像的服务器文件名
            avatarServerFileName: '',
            // 头像的base64值
            avatarBase64: '',
            // 学号(用于更改)
            sid: '',
            // 类型，增加学生、修改学生
            type: '',
            // 学院专业和班级的数据，默认是空的，从Ajax来
            // 已经经过数据格式转换的
            cmcOptions: [],
            // 全部的民族
            allNationality: '汉族、壮族、回族、满族、维吾尔族、苗族、彝族、土家族、藏族、蒙古族、侗族、布依族、瑶族、白族、朝鲜族、哈尼族、黎族、哈萨克族、傣族、畲族、傈僳族、东乡族、仡佬族、拉祜族、佤族、水族、纳西族、羌族、土族、仫佬族、锡伯族、柯尔克孜族、景颇族、达斡尔族、撒拉族、布朗族、毛南族、塔吉克族、普米族、阿昌族、怒族、鄂温克族、京族、基诺族、德昂族、保安族、俄罗斯族、裕固族、乌孜别克族、门巴族、鄂伦春族、独龙族、赫哲族、高山族、珞巴族、塔塔尔族'.split('、'),
            // 表单的双向绑定的值
            myform: {
                sId: '',
                name: '',
                politics_status: '',
                birthDay: '',
                enrollmentYear: '',
                sex: '',
                state: '',
                nationality: '',
                cmc: [],
                tel: ''
            },
            // 校验规则
            rules: {
                // 学号的校验规则
                sId: [
                    {
                        required: true,
                        message: '亲爱的，必须输入学号哦',
                        trigger: 'blur'
                    },
                    {
                        pattern: /^BK\d{9}$/,
                        message: '亲爱的，就是说啊，学号必须是BK开头，然后9位数字',
                        trigger: 'blur'
                    }
                ],
                // 姓名的校验规则
                name: [
                    {
                        required: true,
                        message: '亲爱的，必须输入学号哦',
                        trigger: 'blur'
                    },
                    {
                        pattern: /^([\u4e00-\u9fa5+\·?\u4e00-\u9fa5+]{2,30}$)/,
                        message: '亲爱的，就是说啊，姓名必须是身份证上的，不能乱七八糟的符号',
                        trigger: 'blur'
                    }
                ],
                // 性别的校验规则
                sex: [
                    {
                        required: true,
                        message: '亲爱的，必须选择性别哦',
                        trigger: 'blur'
                    }
                ],
                // 手机号的校验规则
                tel: [
                    {
                        required: true,
                        message: '亲爱的，必须输入手机号哦',
                        trigger: 'blur'
                    },
                    {
                        pattern: /^(13[0-9]|14[579]|15[0-3,5-9]|16[4-6,7-9]|17[0135678]|18[0-9]|19[89])\d{8}$/,
                        message: '亲爱的，就是说啊，手机必须是11位数字，且必须是符合条件的三个数字开头。',
                        trigger: 'blur'
                    }
                ],
                // 政治面貌的校验规则
                politics_status: [
                    {
                        required: true,
                        message: '亲爱的，必须选择政治面貌哦',
                        trigger: 'blur'
                    },
                ],
                // 生日的校验规则
                birthDay: [
                    {
                        required: true,
                        message: '亲爱的，必须选择生日哦',
                        trigger: 'blur'
                    },
                ],
                // 学院专业和班级的校验规则
                cmc: [
                    {
                        required: true,
                        message: '亲爱的，必须选择学院专业和班级哦',
                        trigger: 'blur'
                    },
                ],
                // 入学年份的校验规则
                enrollmentYear: [
                    {
                        required: true,
                        message: '亲爱的，必须选择学院专业和班级哦',
                        trigger: 'blur'
                    },
                ],
                state: [
                    {
                        required: true,
                        message: '亲爱的，必须选择学院专业和班级哦',
                        trigger: 'blur'
                    }
                ],
                nationality: [
                    {
                        required: true,
                        message: '亲爱的，必须选择学院专业和班级哦',
                        trigger: 'blur'
                    }
                ]
            }
        }
    },
    // 计算后的值
    computed: {
        // 学院、专业、班级的名字数组
        // 说白了，就是从id数组，对应生成一个name数组
        cmcName() {
            let result = [];
            for (let i = 0; i < this.cmcOptions.length; i++) {
                if (this.cmcOptions[i].value == this.myform.cmc[0]) {
                    result.push(this.cmcOptions[i].label);
                    let majors = this.cmcOptions[i].children;

                    for (let j = 0; j < majors.length; j++) {
                        if (majors[j].value == this.myform.cmc[1]) {
                            result.push(majors[j].label);

                            let classes = majors[j].children;

                            for (let k = 0; k < classes.length; k++) {
                                if (classes[k].value == this.myform.cmc[2]) {
                                    result.push(classes[k].label);
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }
    },
    methods: {
        // 裁切！
        doCut() {
            // 从子组件中得到数据
            let {w, h, x, y, imageOriginW, big_image_box_w} = this.$refs.CutImageDialogInn.$data;

            console.log(w, h, x, y, imageOriginW, big_image_box_w);

            // 宽高比
            let rate = imageOriginW / big_image_box_w;

            // 发给服务器，所有数据都要乘宽高比
            serverDoCut({
                x: x * rate,
                y: y * rate,
                w: w * rate,
                h: h * rate,
                filename: this.serverOfilename
            }).then(data => {
                console.log(data.info);
                this.avatarServerFileName = data.info;
                this.showCutDialog = false;
            });
        },
        // 回显数据
        showBackData(resData) {
            // 回显所有属性
            this.myform = {...resData};

            this.avatarServerFileName = resData.avatar;
            this.serverOfilename = resData.avatar;

            // 回显CMC属性
            this.myform.cmc = [
                resData.collegeId,
                resData.majorId,
                resData.classId
            ];
        },
        // 确定增加学生按钮
        addStudent() {
            // 校验全表
            this.$refs.myform.validate(async (isok) => {
                // isok是布尔值，true表示没错了，false就表示有错误
                if (isok) {
                    // 得到子组件的数据。data、computed值都可以直接点儿
                    const myform = this.myform;
                    const cmcName = this.cmcName;

                    // 增加学生
                    await addStudent({
                        "sId": myform.sId,
                        "name": myform.name,
                        "collegeName": cmcName[0],
                        "collegeId": myform.cmc[0],
                        "majorId": myform.cmc[1],
                        "majorName": cmcName[1],
                        "classId": myform.cmc[2],
                        "className": cmcName[2],
                        "sex": myform.sex,
                        "tel": myform.tel,
                        "enrollmentYear": myform.enrollmentYear,
                        "state": myform.state,
                        "birthDay": myform.birthDay,
                        "politics_status": myform.politics_status,
                        "nationality": myform.nationality,
                        "avatar": this.avatarServerFileName
                    }).then(() => {
                        // 成功
                        // 提示框，this.$message.success()是ElementUI的用法，表示弹出成功提示
                        this.$message.success('增加学生成功');
                        // 跳转
                        this.$router.push({
                            name: '学生列表'
                        });
                    }, (res) => {
                        // 失败
                        // 提示框，this.$message.error()是ElementUI的用法，表示弹出错误提示
                        this.$message.error(res.response.data.info)
                    });
                }
            });
        },
        // 确定增加学生按钮
        modifyStudent() {
            // 校验全表
            this.$refs.myform.validate((isok) => {
                // isok是布尔值，true表示没错了，false就表示有错误
                if (isok) {
                    // 得到子组件的数据。data、computed值都可以直接点儿
                    const myform = this.myform;
                    const cmcName = this.cmcName;

                    // 调用Ajax
                    modifyStudent(this.sid, {
                        "sId": myform.sId,
                        "name": myform.name,
                        "collegeName": cmcName[0],
                        "collegeId": myform.cmc[0],
                        "majorId": myform.cmc[1],
                        "majorName": cmcName[1],
                        "classId": myform.cmc[2],
                        "className": cmcName[2],
                        "sex": myform.sex,
                        "tel": myform.tel,
                        "enrollmentYear": myform.enrollmentYear,
                        "state": myform.state,
                        "birthDay": myform.birthDay,
                        "politics_status": myform.politics_status,
                        "nationality": myform.nationality,
                        "avatar": this.avatarServerFileName
                    }).then(() => {
                        // 成功
                        // 提示框，this.$message.success()是ElementUI的用法，表示弹出成功提示
                        this.$message.success('修改学生成功');
                        // 跳转
                        this.$router.push({
                            name: '学生列表'
                        });
                    }, (res) => {
                        // 失败
                        // 提示框，this.$message.error()是ElementUI的用法，表示弹出错误提示
                        this.$message.error(res.response.data.info)
                    });
                }
            });
        },
        // 处理CMC的数据
        handleCmcToSelectTree(resData) {
            // 形式转换一下（以后工作每天都是这种事儿）
            // 对接口，是前端的宿命。
            this.cmcOptions = resData.map(item1 => ({
                label: item1.collegeName,
                value: item1.collegeId,
                children: item1.majors.map(item2 => ({
                    label: item2.majorName,
                    value: item2.majorId,
                    children: item2.classes.map(item3 => ({
                        label: item3.className,
                        value: item3.classId
                    }))
                }))
            }));
        },
        // 点击添加头像框
        add_avatar_btn() {
            // 得到隐藏的那个框框
            let kuang = this.$refs.file_kuang;

            // 创建一个事件document.createEvent()
            var ev = document.createEvent('MouseEvents');
            // 初始化这个事件为点击事件
            ev.initEvent("click", true, true);
            // 发出这个事件
            kuang.dispatchEvent(ev);

        },
        // 选择图片完毕
        pick_picture_done(e) {
            let file = e.target.files[0];

             
            // 虚拟表单
            let fd = new FormData();
            fd.append('file', file);

            // 上传
            uploadAvatar(fd).then(
                (res) => {
                    this.serverOfilename = res.info;
                    // 上传成功
                    // 设置头像的服务器返回的文件名
                    // this.avatarServerFileName = res.info;
                    this.picURL = 'http://www.zkt-it.com:5050/images/student_avatar/' + res.info;
                    // 弹出层显示
                    this.showCutDialog = true;
                }, 
                (res) => {
                    // 上传失败
                    this.$message.error(res.response.data.info);
                }
            );
            
            
            /*********** 上传时机-第二种情况，先上传前预览，点击按钮之后才上传 **********
            // 文件读取器，是JS内置的
            let fr = new FileReader();
            // DataURL俗称base64地址
            fr.readAsDataURL(file); 
            // 当图片base64加密好（特别快）
            fr.onload = (e) => {
                this.avatarBase64 = e.target.result;
            }
            */
        }
    },
}
</script>

<style lang="less" scoped>
.add_avatar_btn {
    width: 100px;
    height: 100px;
    border: 1px solid rgb(203, 202, 202);
    position: relative;
    // 鼠标碰到，是小手
    cursor: pointer;
    // 背景尺寸，让图片能够完整容纳在盒子中
    background-size: contain;
    // 背景不重复
    background-repeat: no-repeat;
    // 背景居中
    background-position: center center;

    span {
        position: absolute;
        font-size: 40px;
        width: 40px;
        height: 40px;
        // 绝对定位居中
        top: 50%;
        left: 50%;
        margin-left: -20px;
        margin-top: -20px;
        text-align: center;
        line-height: 40px;
        // 过渡。让变化以动画形式发生。
        transition: all 1s;
    }


    // 它自己被hover的时候，里面的span
    &:hover span {
        color: red;
        // transform表示变形，rotate表示旋转，scale表示放大
        transform: scale(3);
    }
}
</style>